package yxy.cherry.paycenter.util;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;

import com.alibaba.fastjson.JSONObject;

import yxy.apple.http.HTTPConnection;
import yxy.apple.http.request.JSONRequest;
import yxy.apple.http.response.JSONResponse;
import yxy.apple.logger.Logger;

public class HttpUtil {

	private static final Logger logger = Logger.create(HttpUtil.class);

	public static JSONObject response(String url, int timeout, JSONObject body) throws Exception {
		HTTPConnection connection = null;
		try {
			connection = new HTTPConnection(timeout);
			JSONRequest jsonRequest = new JSONRequest(url);
			jsonRequest.setHeader("Content-Type", "application/json");
			jsonRequest.setBody(body);
			JSONResponse response = connection.request(jsonRequest, JSONResponse.class);
			
			JSONObject result = response.body();
			return result;
		} catch (Exception e) {
			throw e;
		} finally {
			if (connection != null) {
				connection.close();
			}
		}
	}
	
	public static JSONObject getHeaderData(HttpServletRequest req) {
		JSONObject datajson = new JSONObject();

		Enumeration<String> headernames = req.getHeaderNames();
		while (headernames.hasMoreElements()) {
			String name = headernames.nextElement();
			String value = req.getHeader(name);
			System.out.println("getHeaderData  " + name + ":" + value);
			datajson.put(name, value);
		}
		
		return datajson;
	}
	
	public static String getPostData(HttpServletRequest req) {
		String datastr = null;
		byte[] data = null;

		try {
			ServletInputStream sis = req.getInputStream(); 
			int len = req.getContentLength();
			if (len >= 0) {
				data = new byte[len];
				int off = 0;
				while (off < len) {
					int read = sis.read(data, off, len - off);
					if (read < 0)
						throw new IOException();
					off += read;
				}
			} else {
				ByteArrayOutputStream baos = new ByteArrayOutputStream();
				byte[] buffer = new byte[4096];
				for (;;) {
					int read = sis.read(buffer, 0, buffer.length);
					if (read < 0)
						break;
					baos.write(buffer, 0, read);
				}
				baos.close();
				data = baos.toByteArray();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		try {
			datastr = new String(data, "UTF-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}

		return datastr;
	}

	public static void printlnParseMap(String method, HttpServletRequest req) {
		logger.info("//********* Http Parse:" + method);
		Map<String, String[]> map = req.getParameterMap();
		Set<String> set = map.keySet();
		for (String key : set) {
			String[] str = map.get(key);
			System.out.println("key:" + key + "     value:" + str[0]);
		}
		logger.info("*************************//");
	}

	public static JSONObject getParseJSON(HttpServletRequest req) {
		JSONObject obj = new JSONObject();
		Map<String, String[]> map = req.getParameterMap();
		Set<String> set = map.keySet();
		for (String key : set) {
			String[] str = map.get(key);
			obj.put(key, str[0]);
		}
		logger.info("http parse json:" + obj.toJSONString());
		return obj;
	}

	/**
	 * 返回信息
	 * 
	 * @param sendobj
	 * @param resp
	 */
	public void returnInfoTo(JSONObject sendobj, HttpServletResponse resp) {
		PrintWriter pw = null;
		resp.addHeader("Access-Control-Allow-Origin", "*");

		try {
			pw = resp.getWriter();
			pw.write(sendobj.toJSONString());
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (pw != null)
				pw.close();
		}
	}

	/**
	 * 返回信息到渠道
	 * 
	 * @param data
	 * @param resp
	 */
	public void returnInfo(String data, HttpServletResponse resp) {
		PrintWriter pw = null;
		resp.addHeader("Access-Control-Allow-Origin", "*");

		try {
			pw = resp.getWriter();
			pw.write(data);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (pw != null)
				pw.close();
		}
	}

	public static String getMD5(String str) {
		try {
			// 生成一个MD5加密计算摘要
			MessageDigest md = MessageDigest.getInstance("MD5");
			// 进行utf-8编码
			byte[] bs = str.getBytes("utf-8");
			// 计算md5函数
			md.update(bs);
			// digest()最后确定返回md5 hash值，返回值为8为字符串。因为md5 hash值是16位的hex值，实际上就是8位的字符
			// BigInteger函数则将8位的字符串转换成16位hex值，用字符串来表示；得到字符串形式的hash值
			// return new BigInteger(1, md.digest()).toString(16);
			byte[] md5sum = md.digest();
			return toHex(md5sum);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	public static String toHex(byte[] data) {
		char[] HEX_DIGITS = "0123456789ABCDEF".toCharArray();
		char[] chars = new char[data.length * 2];
		for (int i = 0; i < data.length; i++) {
			chars[i * 2] = HEX_DIGITS[(data[i] >> 4) & 0xf];
			chars[i * 2 + 1] = HEX_DIGITS[data[i] & 0xf];
		}
		return new String(chars);
	}

	public static String getURLEncoderString(String str) {
		String result = "";
		if (null == str) {
			return "";
		}
		try {
			result = java.net.URLEncoder.encode(str, "UTF-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return result;
	}

	public static String getSignData(JSONObject parseobj, String nosignkey) {
		// params为要参与签名的参数键值对.
		StringBuffer content = new StringBuffer();
		// 按照key做排序

		Set<String> parseset = parseobj.keySet();
		List<String> list = sortSet(parseset);

		for (int i = 0; i < list.size(); i++) {
			String key = list.get(i);
			if ("sign".equals(key))
				continue;
			if (nosignkey != null) {
				if (nosignkey.equals(key)) {
					continue;
				}
			}
			String value = parseobj.getString(key);
			if (value != null) {
				content.append((i == 0 ? "" : "&") + key + "=" + value);
			}
		}
		return content.toString();
	}
	
	public static String getSignData(JSONObject parseobj, String scretkey, String secret) {
		// params为要参与签名的参数键值对.
		StringBuffer content = new StringBuffer();
		// 按照key做排序

		Set<String> parseset = parseobj.keySet();
		List<String> list = sortSet(parseset);

		for (int i = 0; i < list.size(); i++) {
			String key = list.get(i);
			if ("sign".equals(key))
				continue;
			
			String value = parseobj.getString(key);
			if (value != null) {
				content.append((i == 0 ? "" : "&") + key + "=" + value);
			}
		}

		if (scretkey != null) {
			content.append("&").append(scretkey).append("=");			
		}

		if(secret != null) {
			content.append(secret);			
		}
		return content.toString();
	}

	public static List<String> sortSet(Set<String> set) {
		List<String> strlist2 = new ArrayList<>();
		strlist2.addAll(set);
		Collections.sort(strlist2);

		return strlist2;
	}

	public static NameValuePair[] getValuePair(JSONObject parseobj) {
		NameValuePair[] pair = new NameValuePair[parseobj.size()];

		Set<String> set = parseobj.keySet();
		int i = 0;
		for (String key : set) {
			pair[i] = new BasicNameValuePair(key, parseobj.getString(key));
			i++;
		}

		return pair;
	}
	
	public static String getPostContent(HttpServletRequest req) {
		BufferedReader reader = null;
		String line = null;
		StringBuilder sb = new StringBuilder();
		try {
			reader = req.getReader();

			while ((line = reader.readLine()) != null) {
				sb.append(line);
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return sb.toString();
	}
	
	public static JSONObject URLRequestJson(String URL) {
		JSONObject jobj = new JSONObject();
		String[] arrSplit = null;

		String strUrlParam = TruncateUrlPage(URL);
		if (strUrlParam == null) {
			return jobj;
		}
		// 每个键值为一组
		arrSplit = strUrlParam.split("[&]");
		for (String strSplit : arrSplit) {
			String[] arrSplitEqual = null;
			arrSplitEqual = strSplit.split("[=]");

			// 解析出键值
			if (arrSplitEqual.length > 1) {
				// 正确解析
				jobj.put(arrSplitEqual[0], arrSplitEqual[1]);
			} else {
				if (arrSplitEqual[0] != "") {
					// 只有参数没有值，不加入
					jobj.put(arrSplitEqual[0], "");
				}
			}
		}
		return jobj;
	}
	
	/**
	 * 去掉url中的路径，留下请求参数部分
	 * 
	 * @param strURL
	 *            url地址
	 * @return url请求参数部分
	 */
	private static String TruncateUrlPage(String strURL) {
		String strAllParam = null;
		String[] arrSplit = null;

		strURL = strURL.trim();

		arrSplit = strURL.split("[?]");
		if (strURL.length() > 1) {
			if (arrSplit.length > 1) {
				if (arrSplit[1] != null) {
					strAllParam = arrSplit[1];
				}
			} else {
				strAllParam = arrSplit[0];
			}
		}

		return strAllParam;
	}
}
